#pragma once
// -------------------------------------------------
// ZED Kit
// -------------------------------------------------
//   File Name: vector.hpp
//      Author: Ziming Li
//     Created: 2023-10-07
// -------------------------------------------------
// Copyright (C) 2023 MingYang Software Technology.
// -------------------------------------------------

#ifndef ZED_VECTOR_HPP
#define ZED_VECTOR_HPP

#include "./assert.h"
#include <algorithm>
#include <type_traits>
#include <vector>

namespace zed {

template <class V>
class vector_base
{
public:
    bool contains(const typename V::value_type& o) const {
        return m_std.end() != std::find(m_std.begin(), m_std.end(), o);
    }
protected:
    explicit constexpr vector_base(V& v) : m_std(v) {}
    V& m_std;
};

template <typename T, class A>
class const_vector : public vector_base<const std::vector<T, A>>
{
public:
    using vector_type = std::vector<T, A>;
    explicit constexpr const_vector(const vector_type& v) : vector_base<const vector_type>(v) {}
};

template <typename T, class A>
class vector : public vector_base<std::vector<T, A>>
{
public:
    using vector_type = std::vector<T, A>;
    explicit constexpr vector(vector_type& v) : vector_base<vector_type>(v) {}

    void append(const vector_type& v) { this->m_std.insert(this->m_std.end(), v.begin(), v.end()); }

    void erase_at(size_t i);
};

template <typename T, class A>
vector<T, A> wrap(std::vector<T, A>& v) { return vector<T, A>(v); }

template <typename T, class A>
const_vector<T, A> wrap(const std::vector<T, A>& v) { return const_vector<T, A>(v); }

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Implementations

template <typename T, class A>
void vector<T, A>::erase_at(size_t i)
{
    ZASSERT(i < this->m_std.size());
    this->m_std.erase(this->m_std.begin() + i);
}

} // namespace zed

#endif // ZED_VECTOR_HPP
